﻿
using Dapper;
 
using System; 
using System.Collections.Generic;
using System.Data; 
using System.Linq; 

namespace hCommand {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：Component                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/9/2 11:28:16                        
   *└────────────────────────────────────────────────┘
   **/
    public abstract class AbsTaskCSEngine : AbsTaskComp {

        /// <summary>
        /// 移库任务
        /// </summary>

        /// <returns></returns>
        public long abdicationMove(AbsCoreStock cs, List<long> deepScrList) {
            //将该浅货位的货物移动到该浅货位同组下的空货位  csdList[0].rLoctionId==null ? 0: csdList[0].rLoctionId
            var whLoc = getById<CoreWhLoc>(cs.locId);
            if (whLoc == null) {
                throw new Exception(cs.boxCode + "不在库存");
            }
            List<CoreWhLoc> locList = getLoc4SelectIn(whLoc.areaId, whLoc.moveGroup );
            for (int i = 0; i < locList.Count; i++) {
                if (deepScrList.Contains(locList[i].scr)) {
                    locList.RemoveAt(i);
                    i--;
                }
            }
            CoreWhLoc des = I18nConfig.select(locList, cs.deepDiff, cs);//每个moveGroup 必须有一个空货位共移库
            int desId = TaskNoUtil.virtual_Loc;
            if (des != null) {
                desId = (int)des.id;
            }

            return locMoreMove(cs, desId );
        }

     

        public long locMoreMove(AbsCoreStock cs, long des) {
            //将该浅货位的货物移动到该浅货位同组下的空货位  csdList[0].rLoctionId==null ? 0: csdList[0].rLoctionId
            var whLoc =getById<CoreWhLoc>(cs.locId);
            if (whLoc == null) {
                throw new Exception(cs.boxCode + "不在库存");
            }
            TaskResDto res = createTask( cs, (int)des);
            long stockId = cs.id;
            int src = cs.locId; 
            long goodDiff = cs.deepDiff; 
            if (I18nConfig.isLoc(src)) {
                if (I18nConfig.isLoc(des)) {
                    UpdateStock( stockId, StockStatus.移库中);
                    LocCoreUtil.UpdataWhLoc(this, src, goodDiff);
                    LocCoreUtil.UpdataWhLoc(this, des, goodDiff);
                } else {
                    UpdateStock( stockId, StockStatus.出库中);
                    LocCoreUtil.UpdataWhLoc(this, src, goodDiff);
                }

            } else {
                if (I18nConfig.isLoc(des)) {
                    UpdateStock(  stockId, StockStatus.入库中);
                    LocCoreUtil.UpdataWhLoc(this, des, goodDiff);
                } else {
                    UpdateStock(  stockId, StockStatus.库外移动);
                }
            }
            return res.paramId;
        } 
        public TaskResDto createOutTask( AbsCoreStock cs, int des, string relay = "") {
            long goodDiff = cs.deepDiff;
            TaskResDto res = createTask( cs, des, relay);
            UpdateStock( cs.id, change2Status());
            LocCoreUtil.UpdataWhLoc(this, cs.locId, goodDiff);
            return res;
        }
        public TaskResDto createInTask(AbsCoreStock cs, int des,  String relay = "") {
            if (0 == des || null == cs) {
                throw new Exception(cs.id + " 任务下发失败！");
            }
            TaskResDto res = createTask(  cs, des, relay);
            UpdateStock(  cs.id, change2Status());
            LocCoreUtil.UpdataWhLoc(this, des, cs.deepDiff);
            return res;
        }


        abstract protected StockStatus change2Status();

        public bool UpdateStock( long stockId, StockStatus status) {
            string sql = "update  Core_Stock set status=@status , change_Time=sgj_get_sys_now where id=@Id";
            int count = exec(sql, new { id = stockId, status = (int)status });
            return true;
        }


        public long getRelayId<CS>(  CS cs, List<long> deepScrList) where CS : AbsCoreStock {
            long relyId = 0;
            var whLoc = getById<CoreWhLoc>(cs.locId);
            if (whLoc == null || whLoc.deepIndex == 1) {
                return relyId;
            }
            //浅货位,存在入库中任务时
            var whLocShallow =queryUnique<CoreWhLoc>("select * from Core_Wh_Loc where  scr=@scr and deep_Index=1", whLoc);
            if (whLocShallow == null) {
                throw new Exception("未找到该浅货位信息,无法进行深货位取货!");
            }
            if (whLocShallow.countStock == 0) {
                return 0;
            }
            string sql = "select * from  Core_Stock where loc_Id=@locId";
            CS csShallow = query<CS>(sql, new { locId = whLocShallow.id }).FirstOrDefault();
            if (csShallow == null) {
                throw new Exception("浅货位货位 " + whLocShallow.id + " 的货位状态有误，不能进行移库");
            }
            //whLocShallow 不用判断为空，为空表示数据库 库位信息不完整

            if (whLocShallow.workingCount() == 0) {

                relyId = abdicationMove(csShallow, deepScrList );
                if (relyId == 0) {
                    throw new Exception("移库浅货位失败" + whLocShallow.id);
                }
                return relyId;
            } else {
                if (whLocShallow.countIn > 0) {
                    throw new Exception("浅货位正在入库,无法进行深货位取货!");
                } else {
                    relyId = getRelyParamId(  csShallow.id, whLocShallow);
                }
            }
            return relyId;
        }
 
    }
}

